package com.luyou.a01;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Locale;
import java.util.Map;

@SpringBootApplication
public class A01Application {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        /*
          是Spring Framework 中的一个接口，它扩展了 ApplicationContext 接口，提供了更多的配置和管理应用上下文的能力。
          ConfigurableApplicationContext 主要用于支持在应用程序上下文初始化和刷新之前对其进行更灵活的配置。
         */
        ConfigurableApplicationContext context = SpringApplication.run(A01Application.class, args);

        //在单利bean默认实现类中获取存储单利已经创建的单例Bean
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        singletonObjects.setAccessible(true);
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
        map.entrySet().stream().filter(e -> e.getKey().startsWith("component"))
                .forEach(e -> System.out.println(e.getKey() + "=" + e.getValue()));

        System.out.println(context.getMessage("thanks", null, Locale.ENGLISH));
        System.out.println(context.getMessage("thanks", null, Locale.SIMPLIFIED_CHINESE));
        System.out.println(context.getMessage("thanks", null, Locale.TRADITIONAL_CHINESE));

        //当前resource下的资源
        Resource[] resources = context.getResources("classpath:application.yml");
        Assert.isTrue(resources.length > 0, "加载类路径下的 application.yml 文件失败");

        // 使用 classpath* 可以加载 jar 里类路径下的 resource
        resources = context.getResources("classpath*:META-INF/spring.factories");
        Assert.isTrue(resources.length > 0, "加载类路径下的 META-INF/spring.factories 文件失败");

        //java_home 是从环境变量中读取，properties.name 则是从 application.yml 配置文件中读取。
        System.out.println(context.getEnvironment().getProperty("java_home"));
        System.out.println(context.getEnvironment().getProperty("properties.name"));

        //注册事件
        context.getBean(Component1.class).register();
        context.close();
    }

}
